// Copyright 2011, Vanya Davidenko.
// Кодировка файла: UTF-8. 
package info.iu9.interval_tree;
import java.util.Iterator;



// Интерфейс множества интервалов целых чисел,
// позволяющего только поиск: проверку наличия числа среди элементов.
// Итератор последовательно возвращает все числа упорядоченные по возрастанию.
public abstract class IntervalSearchSet implements Iterable<Integer>,
                                                   Cloneable {

  // Проверка наличия числа во множестве интервалов.
  public abstract boolean contains(final int v);

  // Выводит в порядке возрастания все числа в строке вида: "1 2 666".
  public String toString() {
    if ( !iterator().hasNext() ) { return ""; }

    final StringBuilder sb = new StringBuilder();
    for ( final Integer i : this ) {
      sb.append(i);
      sb.append(' ');
    }
    sb.setLength(sb.length() - 1);  // удаление последнего пробела
    return sb.toString();
  }


  // Выводит int как юникодные символы.
  public String toUnicodeCharSequenceString() {
    final Iterator i = iterator();
    if ( !i.hasNext() ) { return ""; }

    final StringBuilder sb = new StringBuilder();

    int start = iterator().next();
    int prev = start;
    while ( i.hasNext() ) {
      final int current = (Integer)i.next();
      if ( current - prev > 1 ) {
        appendCharacterSequence(start, prev, sb);
        start = current;
      }
      prev = current;
    }
    appendCharacterSequence(start, prev, sb);
    return sb.toString();
  }


  // Добавление текстового представления интервала [b, e] в строку:
  // если b и e отличаются более чем на единицу: "b-e",
  // если b и e отличаются на единицу: "be",
  // в противном случае: "b".
  // @pre e >= b.
  private static void appendCharacterSequence(final int b, final int e,
                                              final StringBuilder sb) {
    assert e >= b;

    if ( e - b > 1 ) {          // a-c
      sb.appendCodePoint(b);
      sb.append('-');
      sb.appendCodePoint(e);
    } else if ( e != b )  {     // ab
      sb.appendCodePoint(b);
      sb.appendCodePoint(e);
    } else {
      sb.appendCodePoint(b);    // a
    }
  }
}
